#include <modules\fileTerrainModule.h>
#include <base\global.h>
#include <geo\mercatorProjection.h>
#include <io\pngstream.h>
#include <model.h>

#include "Poco\DirectoryIterator.h"
#include <Poco\File.h>
#include <Poco\Path.h>

#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

using Poco::DirectoryIterator;
using Poco::File;
using Poco::Path;

fileTerrainModule::fileTerrainModule(vec2i _tile_res, vec2i _levels_interval, int _level0_offset, string input_xyz_file_) : dataModule() {
  tile_res = _tile_res;
  levels_interval = _levels_interval;
  level0_offset = _level0_offset;
  input_xyz_file = input_xyz_file_;
}

bool
fileTerrainModule::post(model * _model) {

  Poco::Path dir(_model->getDataStorageDir());
  dir.pushDirectory(_model->getModelName());

  Poco::File ofile(Poco::Path(dir.absolute(), _model->getModelName() + ".def"));

  ofstream output(ofile.path().c_str(), ios::app | ios::out | ios::binary);

  output << "fileTerrainModule" << endl;
  output << tile_res[0] << endl;
  output << tile_res[1] << endl;
  output << levels_interval[0] << endl;
  output << levels_interval[1] << endl;
  output << level0_offset << endl;

  output.close();

  // check/create directories for all levels
  dir = _model->getDataStorageDir();
  dir.pushDirectory(_model->getModelName());
  dir.pushDirectory("global_profile");
  dir.pushDirectory(TERRAIN_DIR_BASE_NAME);

  for (int level = levels_interval[0]; level <= levels_interval[1]; level++) {
    stringstream str;
    str << level + level0_offset;
    dir.pushDirectory(str.str());
    Poco::File file(dir);
    file.createDirectories();
    dir.popDirectory();
  }

  // read data /create tiles
  fstream input(input_xyz_file.c_str(), ios::in);
  vec3d point;

  // data was stored first from down to top (y) and then from left to right (x)
  rows_bin = new terrainRowsBin(4, 7201, dir, this);
  if (input.is_open()) {

    // read all tuples (lat, lgn, altitude) (float, float, float)
    vec2i hm_tile;
    int x = 0;
    while (x < 7201) {
      std::cout << hm_tile.x / INTERPOLATED_TERRAIN_TILE_SIZE / 1024 << std::endl;
      for (int y = 0; y != 7201; y++) {
        input >> point.x;
        input >> point.y;
        input >> point.z;

        vec2d tiled = mercatorProjection::getTiled(geoLocation(point.x, point.y), 19) * INTERPOLATED_TERRAIN_TILE_SIZE;
        hm_tile = vec2i(ROUND(tiled[0]), ROUND(tiled[1]));

        point.x = hm_tile.x;
        point.y = hm_tile.y;
       
        if ((hm_tile.x / INTERPOLATED_TERRAIN_TILE_SIZE / 1024) > 276.200) {
          rows_bin->insertPoint(x, y, point); // (row, row_index)
        }
      }

      x++;
    }
  }

  delete rows_bin;

  input.close();

  return true;
}